package com.mashibing.mall.product.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.mashibing.common.algorithm.TreeNodeUtils;
import com.mashibing.common.algorithm.TreeNode;
import com.mashibing.mall.product.service.CategoryBrandRelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mashibing.common.utils.PageUtils;
import com.mashibing.common.utils.Query;

import com.mashibing.mall.product.dao.CategoryDao;
import com.mashibing.mall.product.entity.CategoryEntity;
import com.mashibing.mall.product.service.CategoryService;
import org.springframework.transaction.annotation.Transactional;


@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    @Autowired
    private CategoryBrandRelationService categoryBrandRelationService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 获取三级分类树
     * @param params
     * @return
     */
    @Override
    public List<TreeNode<CategoryEntity>> getCategoryTree(Map<String, Object> params) {

        List<CategoryEntity> categoryEntityList = this.list();
        List<TreeNode<CategoryEntity>> nodeList = new ArrayList<>();
        // Comparator.comparingInt 默认是升序排序。如果要实现降序排序，可以通过 reversed() 方法来反转排序顺序
        // Comparator.comparingInt(YourClass::yourMethod).reversed()
        categoryEntityList.stream().sorted(Comparator.comparingInt(CategoryEntity::getSort)).forEach(categoryEntity -> {
            TreeNode<CategoryEntity> node = new TreeNode<>();
            node.setId(categoryEntity.getCatId());
            node.setEntity(categoryEntity);
            node.setName(categoryEntity.getName());
            node.setParentId(categoryEntity.getParentCid());
            nodeList.add(node);
        });
        return TreeNodeUtils.getTreeListByBFS(nodeList);
    }

    /**
     * 根据分类 id 列表批量删除分类
     * @param catIds
     */
    @Override
    public void removeCategoryByIds(List<Long> catIds) {
        // TODO  1.检查类别数据是否在其他业务中使用

        // 2.批量逻辑删除操作
        this.removeByIds(catIds);
    }

    /**
     * 同步冗余的类别数据
     * @param category
     */
    @Transactional
    @Override
    public void updateDetail(CategoryEntity category) {
        // 1.更新原始数据
        this.updateById(category);
        if (ObjectUtil.isNotEmpty(category.getName())) {
            // 同步更新级联的数据
            categoryBrandRelationService.updateCategoryName(category.getCatId(), category.getName());
            // todo 同步更新其他冗余数据
        }
    }

    /**
     * 根据三级分类查找类别路径 id 数组
     */
    @Override
    public Long[] findCatelogPath(Long catelogId) {
        List<Long> paths = new ArrayList<>();
        List<Long> parentPath = this.findParentPath(catelogId, paths);
        Collections.reverse(parentPath);
        return parentPath.toArray(new Long[parentPath.size() - 1]);
    }

    /**
     * 递归查找指定分类 id 的父 id，并填充到数组中
     */
    private List<Long> findParentPath(Long catelogId, List<Long> paths) {
        paths.add(catelogId);
        // 根据分类 id 查找分类
        CategoryEntity category = this.getById(catelogId);
        // 如果分类的父 id 不为 0
        if (ObjectUtil.notEqual(category.getParentCid(), 0L)) {
            // 递归查找当前分类的父 id 的父 id
            this.findParentPath(category.getParentCid(), paths);
        }
        return paths;
    }
}
